package com.jinglan.hlht.service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.jinglan.framework.common.OrderState;
import com.jinglan.framework.util.httpclient.HttpHelper;
import com.jinglan.framework.util.md5.MD5Util;
import com.jinglan.framework.util.string.StringUtil;
import com.jinglan.qcoin.center.pojo.QcoinChannelOrder;

@Service
public class HlhtService {
	@Value("${orderUrl}")
	private String orderUrl;// 下单地址
	@Value("${queryOrderUrl}")
	private String queryOrderUrl;// 查单地址
	@Value("${queryBalanceUrl}")
	private String queryBalanceUrl;// 查余额
	@Value("${appKey}")
	String appKey;// 商户Id
	@Value("${itemId}")
	String itemId;// v39平台商品Id
	private String encoding = "UTF-8";
	@Value("${version}")
	String version;// 当前文档版本号
	@Value("${secretKey}")
	private String secretKey;// 秘钥
	@Value("${callbackUrl}")
	private String callbackUrl;// 回调地址
	private Integer requestTimeOut = 38000;// 请求超时时间
	private Logger logger = LoggerFactory.getLogger(HlhtService.class);

	// 下单
	public QcoinChannelOrder placeOrder(String msgHead, String channelOrderNo, long rechargeAmount, String number,
			String ip) {
		QcoinChannelOrder rstChannelOrder = getHandlingOrder(channelOrderNo);
		TreeMap<String, String> map = new TreeMap<>();
		map.put("appKey", appKey);// 商户ID
		map.put("merOrderId", channelOrderNo);// 商户订单号
		map.put("itemId", itemId);// v39平台商品Id
		map.put("number", number);// 游戏账号
		map.put("itemPrice", rechargeAmount / 1000 + "");// 充值面额
		map.put("callBackUrl", callbackUrl);// 回调的URL
		map.put("ip", ip);// 充值账户ip
		map.put("version", version);// 当前文档版本号
		// 组织签名原串
		String signData = sortSrcSignData(map);
		logger.info("签名原串:" + signData);
		String sign = MD5Util.encrypt(signData, encoding);
		map.put("sign", sign);// 当前文档版本号
		try {
			String postResult = HttpHelper.executePostString(orderUrl, map, "UTF-8", requestTimeOut);
			if (postResult == null || postResult.contains("<html")) {
				return rstChannelOrder;
			}
			// 正常处理
			logger.info(msgHead + "上游返回原始数据：" + postResult+"------11");
			rstChannelOrder.setChannelResult(postResult);
			// 对上游参数进行解析
			JSONObject rspObj = JSONObject.parseObject(postResult);
			// 返回状态码
			String errorCode = rspObj.getString("errorCode");
			// 成功或者失败
			String rsSuccess = rspObj.getString("success");
			if ("false".equals(rsSuccess)) {
				OrderState thisOrderState = getOrderState(msgHead, errorCode); // 返回订单的状态
				rstChannelOrder.setOrderState(thisOrderState.getState());
				rstChannelOrder.setOrderStateDesc(thisOrderState.getStateDesc());
				rstChannelOrder.setChannelState(rsSuccess);//设置订单的失败状态
			} else if ("true".equals(rsSuccess)) {
				rstChannelOrder.setChannelState(rsSuccess);//设置订单的成功状态
				JSONObject jsonData = rspObj.getJSONObject("data");
				JSONObject jsonDetail = null;
				String orderId = null;
				if (jsonData != null) {
					// 获取orderDetail中的值
					jsonDetail = jsonData.getJSONObject("orderDetail");
				}
				if (jsonDetail != null) {
					orderId = jsonDetail.getString("orderId");
					rstChannelOrder.setPartnerOrderNo(orderId);// 上游订单号
				}
			}
		} catch (IOException e) {
			logger.info(msgHead + "接口下单处理异常", e);
		}
		return rstChannelOrder;
	}

	// 下订单状态码的处理
	private OrderState getOrderState(String msgHead, String errorcode) {
		if ("2015".equals(errorcode)) {
			logger.info(msgHead + "余额度不够,不能下单");
			return OrderState.fail;
		} else if ("2000".equals(errorcode)) {
			logger.info(msgHead + "appKey不能为空");
			return OrderState.fail;
		} else if ("2001".equals(errorcode)) {
			logger.info(msgHead + "secretKey不能为空");
			return OrderState.fail;
		} else if ("2002".equals(errorcode)) {
			logger.info(msgHead + "商户订单ID不能为空");
			return OrderState.fail;
		} else if ("2003".equals(errorcode)) {
			logger.info(msgHead + "商品编码不能为空");
			return OrderState.fail;
		} else if ("2004".equals(errorcode)) {
			logger.info(msgHead + "商品面值必须大于0");
			return OrderState.fail;
		} else if ("2005".equals(errorcode)) {
			logger.info(msgHead + "通知回调URL不能为空");
			return OrderState.fail;
		} else if ("2006".equals(errorcode)) {
			logger.info(msgHead + "签名[sign]不能为空");
			return OrderState.fail;
		} else if ("2007".equals(errorcode)) {
			logger.info(msgHead + "签名[sign]检验未通过");
			return OrderState.fail;
		} else if ("2008".equals(errorcode)) {
			logger.info(msgHead + "appKey错误，请检查或者联系客服");
			return OrderState.fail;
		} else if ("2009".equals(errorcode)) {
			logger.info(msgHead + "secretKey错误");
			return OrderState.fail;
		} else if ("2022".equals(errorcode)) {
			logger.info(msgHead + "订单金额小于最小订单，不能提交");
			return OrderState.fail;
		} else if ("2026".equals(errorcode)) {
			logger.info(msgHead + "没有该面值的商品");
			return OrderState.fail;
		} else if ("2027".equals(errorcode)) {
			logger.info(msgHead + "订单已经存在，不能重复下单");
			return OrderState.handling;
		} else {
			logger.info(msgHead + "其他错误");
			return OrderState.fail;
		}
	}

	// 查单
	public QcoinChannelOrder queryOrder(String msgHead, String number, String channelOrderNo, String partnerOrderNo) {
		QcoinChannelOrder rstChannelOrder = getHandlingOrder(channelOrderNo);
		String merOrderId = channelOrderNo;// 商户订单号
		String orderId = partnerOrderNo;
		TreeMap<String, String> treemap = new TreeMap<>();
		treemap.put("appKey", appKey);
		if (StringUtil.isNull(orderId)) {
			treemap.put("merOrderId", merOrderId);
		} else {
			treemap.put("orderId", orderId);// v39订单号
		}
		treemap.put("version", version);
		// 组织签名原串
		String data = sortSrcSignData(treemap);
		String sign = MD5Util.encrypt(data, encoding);
		treemap.put("sign", sign);// sign数据
		try {
			String postResult = HttpHelper.executePostString(queryOrderUrl, treemap, "UTF-8", requestTimeOut);
			if (postResult == null || postResult.contains("<html")) {
				return rstChannelOrder;
			} // 正常处理
			logger.info(msgHead + "上游返回原始数据：" + postResult);
			rstChannelOrder.setChannelResult(postResult);
			// 对上游参数进行解析
			JSONObject rspObj = JSONObject.parseObject(postResult);
			// 返回状态码
			String errorCode = rspObj.getString("errorCode");
			// 成功或者失败
			String rsSuccess = rspObj.getString("success");
			if ("true".equals(rsSuccess)) {
				JSONObject jsondata = rspObj.getJSONObject("data");
				// 返回订单的状态
				OrderState thisOrderState = getOrderQuerySuccessState(msgHead, jsondata);
				rstChannelOrder.setOrderState(thisOrderState.getState());
				rstChannelOrder.setOrderStateDesc(thisOrderState.getStateDesc());
				rstChannelOrder.setChannelState(rsSuccess);//设置订单的成功状态
				
			} else if ("false".equals(rsSuccess)) {
				OrderState thisOrderState = getOrderQueryFailState(msgHead, errorCode);
				rstChannelOrder.setOrderState(thisOrderState.getState());
				rstChannelOrder.setOrderStateDesc(thisOrderState.getStateDesc());
				rstChannelOrder.setChannelState(rsSuccess);//设置订单的失败状态
			}
			return rstChannelOrder;
		} catch (Exception e) {
			logger.info(msgHead + "接口下单处理异常", e);
		}
		return null;

	}

	// 查单失败状态
	private OrderState getOrderQueryFailState(String msgHead, String errorCode) {
		if ("2000".equals(errorCode)) {
			logger.info(msgHead + "appKey不能为空");
			return OrderState.unsure;
		} else if ("2007".equals(errorCode)) {
			logger.info(msgHead + "签名[sign]检验未通过");
			return OrderState.unsure;
		} else if ("2009".equals(errorCode)) {
			logger.info(msgHead + "secretKey错误");
			return OrderState.unsure;
		} else if ("2008".equals(errorCode)) {
			logger.info(msgHead + "appKey错误");
			return OrderState.unsure;
		} else {
			logger.info(msgHead + "其它错误");
			return OrderState.unsure;
		}
	}

	// 查询余额
	public String queryBalance() {
		TreeMap<String, String> treeMap = new TreeMap<>();
		treeMap.put("appKey", appKey);
		treeMap.put("version", version);
		String srcSignData = sortSrcSignData(treeMap);
		String sign = MD5Util.encrypt(srcSignData, encoding);
		treeMap.put("sign", sign);
		String postResult = null;
		try {
			postResult = HttpHelper.executePostString(queryBalanceUrl, treeMap, encoding, requestTimeOut);
			logger.info("返回原始数据:" + postResult);
			if (postResult == null || postResult.contains("<html")) {
				return null;
			}
			JSONObject resultJson = JSONObject.parseObject(postResult);
			String balance = null;
			BigDecimal RsBalance;// 考虑到结果的精度
			String reSuccess = resultJson.getString("success");
			if ("true".equals(reSuccess)) {
				JSONObject dataResJson = resultJson.getJSONObject("data");
				RsBalance = dataResJson.getBigDecimal("balance");
				balance = RsBalance.multiply(new BigDecimal("1000")) + "";
				logger.info("当前余额" + balance + "");
				return balance;
			} else if ("false".equals(reSuccess)) {
				logger.info("查询失败");
			}
		} catch (IOException e) {
			logger.info("查询余额失败", e);
		}

		return null;
	}

	// 查询处理状态码
	private OrderState getOrderQuerySuccessState(String msgHead, JSONObject jsondata) {
		String orderStatus = jsondata.getString("orderStatus");// 取出状态
		if ("processing".equals(orderStatus)) {
			logger.info(msgHead + "订单处理中");
			return OrderState.handling;
		} else if ("importing".equals(orderStatus)) {
			logger.info(msgHead + "已下单");
			return OrderState.handling;
		} else if ("success".equals(orderStatus)) {
			logger.info(msgHead + "成功");
			return OrderState.success;
		} else if ("failed".equals(orderStatus)) {
			logger.info(msgHead + "失败");
			return OrderState.fail;
		} else {
			logger.info(msgHead + "不确定");
			return OrderState.unsure;
		}
	}

	/**
	 * 组织参 数
	 * 
	 * @param jsonObj
	 * 
	 */
	private String sortSrcSignData(TreeMap<String, String> treemap) {
		treemap.put("secretKey", secretKey);
		String data = "";
		for (Entry<String, String> entry : treemap.entrySet()) {
			data += entry.getValue();
		}
		treemap.remove("secretKey");
		return data;
	}

	private QcoinChannelOrder getHandlingOrder(String channelOrderNo) {
		QcoinChannelOrder rstChannelOrder = new QcoinChannelOrder();
		rstChannelOrder.setChannelOrderNo(channelOrderNo);
		rstChannelOrder.setOrderState(OrderState.handling.getState());
		rstChannelOrder.setOrderStateDesc(OrderState.handling.getStateDesc());
		return rstChannelOrder;
	}
}
